﻿using System;
using Nancy;

namespace GeometryServer.Modules
{
    //http://localhost:13775/rest/services/Geometry/GeometryServer/distance?sr=4326&geodesic=true&distanceUnit=9035&geometry1={"geometryType":"GeometryPoint","geometry":{"x":-117.47697998046874,"y":34.121858211839566}}&geometry2={"geometryType":"GeometryPoint","geometry":{"x":-117.41586853027343,"y":34.108125301683316}}
    public class DistanceModule : NancyModule
    {
        public DistanceModule()
            : base("/rest/services/Geometry/GeometryServer/")
        {
            Get["/distance"] = parameters =>
            {
                var model = new Models.Distance();

                var exception = new GISServer.Core.Exception();
                exception.Error = new GISServer.Core.Error
                {
                    Code = 400,
                    Message = "Unable to complete buffer operation."
                };
                #region Parameter

                if (Request.Query["f"].Value == "json")
                {
                    model.Format = Request.Query["f"].Value;
                }
                else
                {
                    model.Format = "HTML";
                }


                if (Request.Query["geometry1"].Value != null)
                {
                    model.Geometry1 = Request.Query["geometry1"].Value;
                }
                if (Request.Query["geometry2"].Value != null)
                {
                    model.Geometry2 = Request.Query["geometry2"].Value;
                }


                if (Request.Query["sr"].Value != null)
                {
                    int value;
                    var successful = int.TryParse(Request.Query["sr"].Value, out value);
                    if (successful)
                    {
                        model.SpatialReference = value;
                    }
                    else
                    {
                        if (!model.HasException)
                        {
                            model.HasException = true;
                        }
                        exception.Error.Details.Add("'sr' parameter is invalid");
                    }
                }

                if (Request.Query["distanceUnit"].Value != null)
                {
                    int value;
                    var successful = int.TryParse(Request.Query["distanceUnit"].Value, out value);
                    if (successful)
                    {
                        model.DistanceUnit = value;
                    }
                    else
                    {
                        if (!model.HasException)
                        {
                            model.HasException = true;
                        }
                        exception.Error.Details.Add("'distanceUnit' parameter is invalid");
                    }

                }

                if ((Request.Query["geodesic"].Value != null) && (Request.Query["geodesic"].Value == "true"))
                {
                    model.Geodesic = true;
                }
                else
                {
                    model.Geodesic = false;
                }

                #endregion

                var output_distance = new GISServer.Core.Client.GeometryService.Distance();

                if ((model.Geometry1 != null) && (model.Geometry2 != null) && (!model.HasException))
                {
                    try
                    {

                        var input_single_geom1 = GISServer.Core.Client.Utilities.Parser.getSingleGeometry(model.Geometry1);
                        var dotspatial_single_geom1 = Services.Utilities.getDotSpatialSingleGeometry(input_single_geom1);

                        var input_single_geom2 = GISServer.Core.Client.Utilities.Parser.getSingleGeometry(model.Geometry2);
                        var dotspatial_single_geom2 = Services.Utilities.getDotSpatialSingleGeometry(input_single_geom2);

                        output_distance = Services.Compute.Distance(dotspatial_single_geom1, dotspatial_single_geom2);
                    }
                    catch (Exception)
                    {
                        if (!model.HasException)
                        {
                            model.HasException = true;
                        }
                        exception.Error.Details.Add("Unable to calculate distance between the geometries");
                    }
                }

                if (!model.HasException)
                {
                    model.Result = output_distance.ToJson();
                }
                else
                {
                    model.Exception = exception.ToJson();
                }


                if (model.Format.Equals("json"))
                {
                    if (!model.HasException)
                    {
                        return Services.Utilities.GetJsonResponseObject(model.Result);
                    }
                    else
                    {
                        return Services.Utilities.GetJsonResponseObject(model.Exception);
                    }

                }
                else
                {
                    return View["Distance", model];
                }

            };

        }
    }
}